package com.ruoyi.web.controller.erpbase;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.SaleOrPurchType;
import com.ruoyi.flowable.service.IFlowDefinitionService;
import com.ruoyi.flowable.service.IFlowTaskService;
import com.ruoyi.system.domain.ApprovalConfig;
import com.ruoyi.system.domain.FlowProcDefDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.Waybills;
import com.ruoyi.system.service.IApprovalConfigService;
import com.ruoyi.system.service.IWaybillsService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 运单Controller
 * 
 * @author he
 * @date 2025-08-18
 */
@Api(tags = "销售运单接口")
@RestController
@RequestMapping("/system/waybills")
public class SaleWaybillsController extends BaseController
{
    @Autowired
    private IWaybillsService waybillsService;

    @Autowired
    private IFlowDefinitionService flowDefinitionService;

    @Autowired
    private IFlowTaskService flowTaskService;

    @Autowired
    private IApprovalConfigService approvalConfigService;

    /**
     * 查询运单列表
     */
    @ApiOperation("查询销售运单信息")
    @PreAuthorize("@ss.hasPermi('system:waybills:list')")
    @GetMapping("/list")
    public TableDataInfo list(Waybills waybills)
    {
        startPage();
        waybills.setType(Long.valueOf(SaleOrPurchType.SALE.getCode()));
        List<Waybills> list = waybillsService.selectWaybillsList(waybills);
        return getDataTable(list);
    }

    /**
     * 导出运单列表
     */
    @ApiOperation("导出销售运单信息")
    @PreAuthorize("@ss.hasPermi('system:waybills:export')")
    @Log(title = "运单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Waybills waybills)
    {
        waybills.setType(Long.valueOf(SaleOrPurchType.SALE.getCode()));
        List<Waybills> list = waybillsService.selectWaybillsList(waybills);
        ExcelUtil<Waybills> util = new ExcelUtil<Waybills>(Waybills.class);
        util.exportExcel(response, list, "运单数据");
    }

    /**
     * 获取运单详细信息
     */
    @ApiOperation("查询销售运单详细信息")
    //@PreAuthorize("@ss.hasPermi('system:waybills:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(waybillsService.selectWaybillsById(id));
    }

    /**
     * 新增运单
     */
    @ApiOperation("新增销售运单信息")
    @PreAuthorize("@ss.hasPermi('system:waybills:add')")
    @Log(title = "运单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Waybills waybills)
    {
        waybills.setType(Long.valueOf(SaleOrPurchType.SALE.getCode()));
        return toAjax(waybillsService.insertWaybills(waybills));
    }

    /**
     * 修改运单
     */
    @ApiOperation("修改销售运单信息")
    @PreAuthorize("@ss.hasPermi('system:waybills:edit')")
    @Log(title = "运单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Waybills waybills)
    {
        waybills.setType(Long.valueOf(SaleOrPurchType.SALE.getCode()));
        return toAjax(waybillsService.updateWaybills(waybills));
    }

    /**
     * 删除运单
     */
    @ApiOperation("删除销售运单信息")
    @PreAuthorize("@ss.hasPermi('system:waybills:remove')")
    @Log(title = "运单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(waybillsService.deleteWaybillsByIds(ids));
    }


    @ApiOperation("销售运单签到")
    @PreAuthorize("@ss.hasPermi('system:waybills:signStateChange')")
    @Log(title = "运单", businessType = BusinessType.UPDATE)
    @PostMapping("/signStateChange")
    public AjaxResult signStateChange(@RequestBody List<Long> ids)
    {
        return toAjax(waybillsService.signStateChange(ids));
    }


    @ApiOperation("回退销售运单")
    @PreAuthorize("@ss.hasPermi('system:waybills:rebackState')")
    @Log(title = "回退运单步骤", businessType = BusinessType.UPDATE)
    @PostMapping("/rebackState")
    public AjaxResult rebackState(@RequestBody Waybills waybills)
    {
        return toAjax(waybillsService.rebackState(waybills));
    }

    /**
     * 批量发起销售运单审批
     */
    @ApiOperation("批量发起销售运单审批")
    @Log(title = "销售运单", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalStart")
    public AjaxResult approvalStart(@RequestBody List<Long> ids)
    {
        // 检查是否启用审批流
        if (!approvalConfigService.isModuleEnabled("sale_waybills")) {
            return error("销售运单模块未启用审批流，请先在审批配置中启用");
        }

        // 获取流程名称
        ApprovalConfig config = approvalConfigService.selectByModuleCode("sale_waybills");
        String flowName = config != null && StringUtils.isNotEmpty(config.getFlowName()) 
                ? config.getFlowName() : "销售运单审核";

        Waybills queryParam = new Waybills();
        queryParam.setType(Long.valueOf(SaleOrPurchType.SALE.getCode()));
        List<Waybills> allWaybills = waybillsService.selectWaybillsList(queryParam);
        
        List<Waybills> waybillsToApprove = new ArrayList<>();
        for (Waybills waybill : allWaybills) {
            if (ids.contains(waybill.getId())) {
                waybillsToApprove.add(waybill);
            }
        }

        if (CollectionUtils.isNotEmpty(waybillsToApprove)) {
            Page<FlowProcDefDto> page = flowDefinitionService.list(flowName, 1, 10);
            List<FlowProcDefDto> records = page.getRecords();
            
            if (CollectionUtils.isEmpty(records)) {
                return error("未找到'" + flowName + "'流程定义，请先配置审批流程");
            }
            
            FlowProcDefDto flowProcDefDto = records.get(0);
            String deploymentId = flowProcDefDto.getDeploymentId();
            String flowId = flowProcDefDto.getId();
            AjaxResult ajaxResult1 = flowTaskService.flowFormData(deploymentId);

            Map<String, Object> variables = new HashMap<>();
            Object o = ajaxResult1.get("data");
            variables.put("formJson", o);

            List<Long> idsToUpdate = new ArrayList<>();
            for (Waybills waybill : waybillsToApprove) {
                variables.put("id", waybill.getId());
                variables.put("waybillNumber", waybill.getNumber());
                variables.put("planName", waybill.getPlanName());
                variables.put("licensePlate", waybill.getLicensePlate());
                variables.put("driverName", waybill.getDriverName());
                variables.put("itemName", waybill.getItemName());
                
                AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById(flowId, variables);
                if (ajaxResult.isSuccess()) {
                    idsToUpdate.add(waybill.getId());
                }
            }

            if (CollectionUtils.isNotEmpty(idsToUpdate)) {
                waybillsService.updateApprovalState(idsToUpdate, SaleOrPurchType.APPROVAL_YN.getCode());
            }
        }

        return toAjax(1);
    }

    /**
     * 审批流结束触发审核完成
     */
    @ApiOperation("销售运单审批完成回调")
    @Log(title = "销售运单", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalEnd")
    public AjaxResult approvalEnd(@RequestBody Long id)
    {
        waybillsService.updateApprovalState(Arrays.asList(id), SaleOrPurchType.APPROVAL_YES.getCode());
        return toAjax(1);
    }
}
